package com.example.demo.aspect;

import cn.hutool.dfa.FoundWord;
import cn.hutool.dfa.SensitiveUtil;
import com.example.demo.annotation.SensitiveWordCheck;
import com.example.demo.enums.SensitiveWordCheckEnum;
import com.example.demo.service.SensitiveWordService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * <p>
 * 敏感词检测
 * <p>
 *
 * @author hzm
 * @date  2022-9-17
 */
@Aspect
@Component
public class SensitiveWordAspect {


    @Pointcut("@annotation(com.example.demo.annotation.SensitiveWordCheck)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint)  throws Throwable {
        MethodSignature signature = ((MethodSignature) joinPoint.getSignature());
        Method method = signature.getMethod();
        Annotation parameterAnnotations = method.getAnnotation(SensitiveWordCheck.class);
        if (parameterAnnotations == null) {
            return joinPoint.proceed();
        }
        Object[] args = joinPoint.getArgs();
        for (Object obj : args) {
            Field[] fields = obj.getClass().getDeclaredFields();
            for (Field field : fields) {
                boolean accessible = field.isAccessible();
                if (!accessible) {
                    field.setAccessible(true);
                }
                SensitiveWordCheck annotation = field.getAnnotation(SensitiveWordCheck.class);
                if (annotation==null) {
                    continue;
                }
                Object o = field.get(obj);
                if (o instanceof String){
                    String content = (String) o;
                    SensitiveWordCheckEnum type = annotation.type();
                    if (SensitiveWordCheckEnum.throwError.equals(type)) {
                        FoundWord foundWord = SensitiveUtil.getFoundFirstSensitive(content);
                        String msg = annotation.throwErrorMsg();
                        String wordStr = "";
                        if (annotation.throwErrorShowWord()) {
                            wordStr = "\"" + foundWord.getFoundWord() + "\"";
                        }
                        msg = msg.replace("$sensitiveWord$", wordStr);
                        throw new RuntimeException(msg);
                    }else if (SensitiveWordCheckEnum.replaceWord.equals(type)) {
                        String str = SensitiveUtil.sensitiveFilter(content, true, null);
                        field.set(obj,  str);
                    }
                }
            }
        }
        return joinPoint.proceed(args);
    }

}
